package com.bsj.pay.util.platform.wsgw.sm;

public class SM3
{
    public static int[] Tj;
    public static final byte[] iv;
    
    static {
        iv = new byte[] { 115, -128, 22, 111, 73, 20, -78, -71, 23, 36, 66, -41, -38, -118, 6, 0, -87, 111, 48, -68, 22, 49, 56, -86, -29, -115, -18, 77, -80, -5, 14, 78 };
        SM3.Tj = new int[64];
        for (int i = 0; i < 16; ++i) {
            SM3.Tj[i] = 2043430169;
        }
        for (int j = 16; j < 64; ++j) {
            SM3.Tj[j] = 2055708042;
        }
    }
    
    public static byte[] CF(final byte[] array, final byte[] array2) {
        return convert(CF(convert(array), convert(array2)));
    }
    
    public static int[] CF(final int[] array, int[] array2) {
        int n = array[0];
        int n2 = array[1];
        int bitCycleLeft = array[2];
        int n3 = array[3];
        int p2 = array[4];
        int n4 = array[5];
        int bitCycleLeft2 = array[6];
        int n5 = array[7];
        final int[][] expand = expand(array2);
        array2 = expand[0];
        final int[] array3 = expand[1];
        int n6 = 0;
        int n7;
        int n8;
        while (true) {
            n7 = n5;
            n8 = n3;
            if (n6 >= 64) {
                break;
            }
            final int bitCycleLeft3 = bitCycleLeft(bitCycleLeft(n, 12) + p2 + bitCycleLeft(SM3.Tj[n6], n6), 7);
            final int bitCycleLeft4 = bitCycleLeft(n, 12);
            final int fFj = FFj(n, n2, bitCycleLeft, n6);
            final int n9 = array3[n6];
            final int gGj = GGj(p2, n4, bitCycleLeft2, n6);
            final int n10 = array2[n6];
            n3 = bitCycleLeft;
            bitCycleLeft = bitCycleLeft(n2, 9);
            n2 = n;
            n = fFj + n8 + (bitCycleLeft3 ^ bitCycleLeft4) + n9;
            n5 = bitCycleLeft2;
            bitCycleLeft2 = bitCycleLeft(n4, 19);
            n4 = p2;
            p2 = P0(gGj + n7 + bitCycleLeft3 + n10);
            ++n6;
        }
        return new int[] { array[0] ^ n, array[1] ^ n2, array[2] ^ bitCycleLeft, array[3] ^ n8, array[4] ^ p2, array[5] ^ n4, array[6] ^ bitCycleLeft2, array[7] ^ n7 };
    }
    
    private static int FF1j(final int n, final int n2, final int n3) {
        return n ^ n2 ^ n3;
    }
    
    private static int FF2j(final int n, final int n2, final int n3) {
        return (n & n2) | (n & n3) | (n2 & n3);
    }
    
    private static int FFj(int n, final int n2, final int n3, final int n4) {
        if (n4 >= 0 && n4 <= 15) {
            n = FF1j(n, n2, n3);
        }
        else {
            n = FF2j(n, n2, n3);
        }
        return n;
    }
    
    private static int GG1j(final int n, final int n2, final int n3) {
        return n ^ n2 ^ n3;
    }
    
    private static int GG2j(final int n, final int n2, final int n3) {
        return (n & n2) | (~n & n3);
    }
    
    private static int GGj(int n, final int n2, final int n3, final int n4) {
        if (n4 >= 0 && n4 <= 15) {
            n = GG1j(n, n2, n3);
        }
        else {
            n = GG2j(n, n2, n3);
        }
        return n;
    }
    
    private static int P0(final int n) {
        rotateLeft(n, 9);
        final int bitCycleLeft = bitCycleLeft(n, 9);
        rotateLeft(n, 17);
        return n ^ bitCycleLeft ^ bitCycleLeft(n, 17);
    }
    
    private static int P1(final int n) {
        return bitCycleLeft(n, 15) ^ n ^ bitCycleLeft(n, 23);
    }
    
    private static byte[] back(final byte[] array) {
        final byte[] array2 = new byte[array.length];
        for (int i = 0; i < array2.length; ++i) {
            array2[i] = array[array2.length - i - 1];
        }
        return array2;
    }
    
    private static int bigEndianByteToInt(final byte[] array) {
        return Util.byteToInt(back(array));
    }
    
    private static byte[] bigEndianIntToByte(final int n) {
        return back(Util.intToBytes(n));
    }
    
    private static int bitCycleLeft(int n, int n2) {
        n2 %= 32;
        final byte[] bigEndianIntToByte = bigEndianIntToByte(n);
        n = n2 / 8;
        n2 %= 8;
        byte[] byteCycleLeft = bigEndianIntToByte;
        if (n > 0) {
            byteCycleLeft = byteCycleLeft(bigEndianIntToByte, n);
        }
        byte[] bitSmall8CycleLeft = byteCycleLeft;
        if (n2 > 0) {
            bitSmall8CycleLeft = bitSmall8CycleLeft(byteCycleLeft, n2);
        }
        return bigEndianByteToInt(bitSmall8CycleLeft);
    }
    
    private static byte[] bitSmall8CycleLeft(final byte[] array, final int n) {
        final byte[] array2 = new byte[array.length];
        for (int i = 0; i < array2.length; ++i) {
            array2[i] = (byte)((byte)((array[i] & 0xFF) << n) | (byte)((array[(i + 1) % array2.length] & 0xFF) >> 8 - n));
        }
        return array2;
    }
    
    private static byte[] byteCycleLeft(final byte[] array, final int n) {
        final byte[] array2 = new byte[array.length];
        System.arraycopy(array, n, array2, 0, array.length - n);
        System.arraycopy(array, 0, array2, array.length - n, n);
        return array2;
    }
    
    private static byte[] convert(final int[] array) {
        final byte[] array2 = new byte[array.length * 4];
        for (int i = 0; i < array.length; ++i) {
            System.arraycopy(bigEndianIntToByte(array[i]), 0, array2, i * 4, 4);
        }
        return array2;
    }
    
    private static int[] convert(final byte[] array) {
        final int[] array2 = new int[array.length / 4];
        final byte[] array3 = new byte[4];
        for (int i = 0; i < array.length; i += 4) {
            System.arraycopy(array, i, array3, 0, 4);
            array2[i / 4] = bigEndianByteToInt(array3);
        }
        return array2;
    }
    
    private static int[][] expand(final int[] array) {
        final int[] array2 = new int[68];
        final int[] array3 = new int[64];
        for (int i = 0; i < array.length; ++i) {
            array2[i] = array[i];
        }
        for (int j = 16; j < 68; ++j) {
            array2[j] = (P1(array2[j - 16] ^ array2[j - 9] ^ bitCycleLeft(array2[j - 3], 15)) ^ bitCycleLeft(array2[j - 13], 7) ^ array2[j - 6]);
        }
        for (int k = 0; k < 64; ++k) {
            array3[k] = (array2[k] ^ array2[k + 4]);
        }
        return new int[][] { array2, array3 };
    }
    
    public static byte[] padding(byte[] back, int n) {
        int n2;
        if ((n2 = 448 - (back.length * 8 + 1) % 512) < 0) {
            n2 = 960 - (back.length * 8 + 1) % 512;
        }
        final byte[] array = new byte[++n2 / 8];
        array[0] = -128;
        final long n3 = back.length * 8 + n * 512;
        final byte[] array2 = new byte[back.length + n2 / 8 + 8];
        System.arraycopy(back, 0, array2, 0, back.length);
        n = 0 + back.length;
        System.arraycopy(array, 0, array2, n, array.length);
        final int length = array.length;
        back = back(Util.longToBytes(n3));
        System.arraycopy(back, 0, array2, n + length, back.length);
        return array2;
    }
    
    public static int rotateLeft(final int n, final int n2) {
        return n << n2 | n >> 32 - n2;
    }
}